﻿#include <fstream>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <stdlib.h>
#include <algorithm>
#include "string"
#include <io.h>
#include "shlwapi.h"
#include <Windows.h>
#include <BaseCommon.h>
#include "out_batch_analysis.h"

using namespace JGG;

// 判断OUT文件中是否都含有所需要的设备信息，1表示设备信息存在，0表示设备信息不齐全
int OutBatchAnalysis::OutFileEquipmentCheck(std::string filename, Out::OutFile out_file)
{
    char ch[500];									//用以存储数据行，及类型判断
    int EquInfoExsit = 0;							//判断设备信息是否存在（0不存在，1存在）

    ifstream fpr;
    fpr.open(filename, ios::in);
    //备份一下设备名
    out_file.unstable_bus_name_backup.clear();
    out_file.unstable_gen_name_backup.clear();
    for (unsigned int i = 0; i < out_file.unstable_gen_name.size(); i++)
    {
        out_file.unstable_gen_name_backup.push_back(out_file.unstable_gen_name[i].c_str());
    }
    for (unsigned int i = 0; i < out_file.unstable_bus_name.size(); i++)
    {
        out_file.unstable_bus_name_backup.push_back(out_file.unstable_bus_name[i].c_str());
    }
    while (fpr)
    {
        fpr.getline(ch, sizeof(ch));
        if (ch[1] == '*'&&ch[2] == ' ')
        {
            for (unsigned int i = 0; i < out_file.unstable_gen_name_backup.size(); i++)
            {
                if (strstr(ch, out_file.unstable_gen_name_backup[i].c_str()))
                {
                    out_file.unstable_gen_name_backup.erase(out_file.unstable_gen_name_backup.begin() + i);//如果这台设备存在就从改写名单中剔除
                }
            }
            for (unsigned int i = 0; i < out_file.unstable_bus_name_backup.size(); i++)
            {
                if (strstr(ch, out_file.unstable_bus_name_backup[i].c_str()))
                {
                    out_file.unstable_bus_name_backup.erase(out_file.unstable_bus_name_backup.begin() + i);//如果这台设备存在就从改写名单中剔除
                }
            }
        }
    }
    fpr.close();
    if ((out_file.unstable_gen_name_backup.size() == 0) && (out_file.unstable_bus_name_backup.size() == 0))
    {
        EquInfoExsit = 1;
    }

    return EquInfoExsit;
}

// 解析相对应的swi文件，利用swi文件完善out信息
void OutBatchAnalysis::UseSwiFileToCompleteOutFile(Swi::SwiFile swi_file, Out::OutFile out_file)
{
    // 循环找到M卡
    for (std::vector<Swi::Region>::iterator region = swi_file.regions.begin(); region != swi_file.regions.end(); region++)
    {
        for (std::vector<Swi::Province>::iterator province = region->provinces.begin(); province != region->provinces.end(); province++)
        {
            for (std::vector<Swi::M>::iterator m = province->generator.m_list.begin(); m != province->generator.m_list.end(); m++)
            {
                // gen_warning
                for (std::vector<Out::GenWarning>::iterator gen_warning = out_file.genwarning_list.begin(); gen_warning != out_file.genwarning_list.end(); gen_warning++)
                {
                    if (strstr(m->name.c_str(), gen_warning->InstabilityEquipmentName1.c_str()))
                    {
                        gen_warning->SWIGenNamewithVol1 = m->name;
                        gen_warning->GenID1 = m->equipment_id;
                    }
                    if (strstr(m->name.c_str(), gen_warning->InstabilityEquipmentName2.c_str()))
                    {
                        gen_warning->SWIGenNamewithVol2 = m->name;
                        gen_warning->GenID2 = m->equipment_id;
                    }
                }

                // bus_warning
                for (std::vector<Out::BusWarning>::iterator bus_warning = out_file.buswarning_list.begin(); bus_warning != out_file.buswarning_list.end(); bus_warning++)
                {
                    if (strstr(m->name.c_str(), bus_warning->InstabilityEquipmentName.c_str()))
                    {
                        bus_warning->SWIBusNamewithVol = m->name;
                    }
                }
            }
        }
    }

}

//重写swi文件
char* OutBatchAnalysis::BatchReWriteSwiFile(BPA::BPAFilesIO::OutParse *inst,
    const char* SwiFileName,
    const char* OutFileName,
    const char* BseFileName,
    int WaveLengthCheckFlag)
{
    ///////////////重写SWI文件///////////
    char SWIStrType[800];
    ofstream   LogOut("LogInfo_OutFilesAnalysis.txt ", ios::app);
    cout << "正在重写SWI文件: " << SwiFileName << endl;
    LogOut << "正在重写SWI文件: " << SwiFileName << endl;
    ////////////开始写入新文件/////////
    ofstream fout;
    fout.open(SwiFileName);
    if (SWIStr.size() > 0)
    {
        for (unsigned int i = 0; i < SWIStr.size(); i++)
        {
            fout << SWIStr[i] << endl;
            strcpy_s(SWIStrType, SWIStr[i].c_str());
            ///到MHC卡时停止写入////
            if (SWIStrType[0] == 'M'&&SWIStrType[1] == 'H'&&SWIStrType[2] == 'C')
            {
                break;
            }
        }

        //开始写入所需卡片

        //写入参考机
        fout << RefferGen;
        //写入G卡
        for (unsigned int i = 0; i < inst->GenWarningInfo.size(); i++)
        {
            if (inst->GenWarningInfo[i].GenID1 != 0)
            {
                fout << "G" << "  " << inst->GenWarningInfo[i].SWIGenNamewithVol1 << " " << inst->GenWarningInfo[i].GenID1 << setw(3) << "3" << setw(60) << "3" << endl;
            }
            if (inst->GenWarningInfo[i].GenID1 == 0)
            {
                fout << "G" << "  " << inst->GenWarningInfo[i].SWIGenNamewithVol1 << " " << " " << setw(3) << "3" << setw(60) << "3" << endl;
            }
            if (inst->GenWarningInfo[i].GenID2 != 0)
            {
                fout << "G" << "  " << inst->GenWarningInfo[i].SWIGenNamewithVol2 << " " << inst->GenWarningInfo[i].GenID2 << setw(3) << "3" << setw(60) << "3" << endl;
            }
            if (inst->GenWarningInfo[i].GenID2 == 0)
            {
                fout << "G" << "  " << inst->GenWarningInfo[i].SWIGenNamewithVol2 << " " << " " << setw(3) << "3" << setw(60) << "3" << endl;
            }
        }
        //写入B卡
        fout << "BH 1" << endl;
        for (unsigned int i = 0; i < inst->BusWarningInfo.size(); i++)
        {
            string InsEquNameTemp = inst->BusWarningInfo[i].InstabilityEquipmentName;
            int StrLength = strlen(inst->BusWarningInfo[i].InstabilityEquipmentName.c_str());
            int SpaceNum = (8 - StrLength);
            for (unsigned int j = 0; j < SpaceNum; j++){
                InsEquNameTemp += " ";
            }
            InsEquNameTemp += inst->BusWarningInfo[i].EquipmentVol;
            inst->BusWarningInfo[i].SWIBusNamewithVol = InsEquNameTemp;
            fout << "B" << "  " << inst->BusWarningInfo[i].SWIBusNamewithVol << "  " << "3" << "  " << "3" << endl;
        }
        fout << "99";
        fout.close();
        cout << "重写完毕。" << endl;
        LogOut << "重写完毕。" << endl;
    }

    //////////重写完毕////////////


    //////////调用swnt.exe,生成新的OUT文件////////
    cout << "开始调用swnt.exe，以生成新的OUT文件..." << endl;
    LogOut << "开始调用swnt.exe，以生成新的OUT文件..." << endl;
    string BpaCmd;
    BpaCmd = " ";
    string BseFileNameTemp = BseFileName;
    BseFileNameTemp = "\"" + BseFileNameTemp + "\"";
    BpaCmd += BseFileNameTemp;	//稳定计算需要输入二进制文件	

    BpaCmd += " ";

    string SwiFileNameTemp = SwiFileName;
    SwiFileNameTemp = "\"" + SwiFileNameTemp + "\"";
    BpaCmd += SwiFileNameTemp;   //稳定计算需要的SWI文件

    string pfntexe = "swnt.exe";
    std::string command = pfntexe + " " + BpaCmd;
    Process processpfnt(command);
    int exit_status = processpfnt.get_exit_status();

    /////////更新新OUT文件的路径，即在OUT文件名前加New/////
    char NewOutFile[500] = "";
    strcpy_s(NewOutFile, OutFileName);
    char *NewOutFileName = NewOutFile;
    cout << "已生成新的OUT文件:" << NewOutFile << endl;
    LogOut << "已生成新的OUT文件:" << NewOutFile << endl;
    ////////更新完毕///////
    return NewOutFileName;
}

//重写swi文件
Swi::SwiFile OutBatchAnalysis::RenewSwiFile(Swi::SwiFile swi_file, Out::OutFile out_file, std::string base_filename)
{
    Swi::SwiFile swi_file;

    // MH
    swi_file.out_control.bh.card_type = "MH";
    swi_file.out_control.bh.card_str = "MH\n";
    // 写入G卡
    for (std::vector<Out::GenWarning>::iterator gen_warning = out_file.genwarning_list.begin(); gen_warning != out_file.genwarning_list.end(); gen_warning++)
    {
        Swi::G g;
        g.card_type = "G";
        std::stringstream oss;
        if (gen_warning->GenID1 != 0)
        {
            oss.str("");
            oss << "G  " << gen_warning->SWIGenNamewithVol1 << " " << gen_warning->GenID1
                << setw(3) << "3" << setw(60) << "3" << endl;
            g.card_str = oss.str();
            swi_file.out_control.g_list.push_back(g);
        }
        if (gen_warning->GenID1 == 0)
        {
            oss.str("");
            oss << "G  " << gen_warning->SWIGenNamewithVol1 << "  " << setw(3) << "3" << setw(60) << "3" << endl;
            g.card_str = oss.str();
            swi_file.out_control.g_list.push_back(g);
        }
        if (gen_warning->GenID2 != 0)
        {
            oss.str("");
            oss << "G  " << gen_warning->SWIGenNamewithVol2 << " " << gen_warning->GenID2
                << setw(3) << "3" << setw(60) << "3" << endl;
            g.card_str = oss.str();
            swi_file.out_control.g_list.push_back(g);
        }
        if (gen_warning->GenID2 == 0)
        {
            oss.str("");
            oss << "G  " << gen_warning->SWIGenNamewithVol2 << "  " << setw(3) << "3" << setw(60) << "3" << endl;
            g.card_str = oss.str();
            swi_file.out_control.g_list.push_back(g);
        }
    }

    // BH
    swi_file.out_control.bh.card_type = "BH";
    swi_file.out_control.bh.card_str = "BH 1\n";
    //写入B卡
    for (std::vector<Out::BusWarning>::iterator bus_warning = out_file.buswarning_list.begin(); bus_warning != out_file.buswarning_list.end(); bus_warning++)
    {
        Swi::B b;
        std::stringstream oss;

        string InsEquNameTemp = bus_warning->InstabilityEquipmentName;;
        int StrLength = strlen(InsEquNameTemp.c_str());
        int SpaceNum = (8 - StrLength);
        for (unsigned int j = 0; j < SpaceNum; j++){
            InsEquNameTemp += " ";
        }
        InsEquNameTemp += bus_warning->EquipmentVol;
        bus_warning->SWIBusNamewithVol = InsEquNameTemp;

        b.card_type = "B";
        oss.str("");
        oss << "B  " << bus_warning->SWIBusNamewithVol << "  " << "3" << "  " << "3" << endl;
        b.card_str = oss.str();
        swi_file.out_control.b_list.push_back(b);
    }

    return swi_file;
}

//out文件数据分析，用于还原功角曲线
void OutBatchAnalysis::OutFileAnalysis(Out::OutFile out_file)
{
    int GenID1 = 0, GenID2 = 0;
    int Gen1Exsit = 0, Gen2Exsit = 0;
    int GenID[2];
    GenID[0] = 0;
    GenID[1] = 0;

    // 统计发电机失稳信息
    for (unsigned int k = 0; k < out_file.genwarning_list.size(); k++)
    {
        if (strstr(out_file.genwarning_list[k].InstabilityJudgeType.c_str(), "功角"))
        {
            if (out_file.gen_info.size() > 0)
            {
                //记录起始发电机序号
                for (unsigned int i = 0; i < out_file.gen_info.size(); i++)
                {
                    if (strstr(out_file.gen_info[i].Name.c_str(), out_file.genwarning_list[k].InstabilityEquipmentName1.c_str()))
                    {
                        Gen1Exsit = 1;
                        GenID1 = i;
                        GenID[0] = i;
                    }
                    if (strstr(out_file.gen_info[i].Name.c_str(), out_file.genwarning_list[k].InstabilityEquipmentName2.c_str()))
                    {
                        Gen2Exsit = 1;
                        GenID2 = i;
                        GenID[1] = i;
                    }
                }
                if (Gen1Exsit == 1 && Gen2Exsit == 1)
                {
                    for (unsigned int genid = 0; genid < 2; genid++)
                    {
                        out_file.time_seq_list.clear();
                        out_file.direction_list.clear();
                        //找出需要修改的周波序号
                        for (unsigned int j = 1; j < out_file.gen_info[GenID[genid]].ATime.size(); j++)
                        {
                            //向上失稳
                            if ((out_file.gen_info[GenID[genid]].Angle[j - 1] > out_file.gen_info[GenID[genid]].Angle[j]))
                            {
                                if (abs(out_file.gen_info[GenID[genid]].Angle[j - 1] - out_file.gen_info[GenID[genid]].Angle[j]) > 200)
                                {
                                    out_file.direction_list.push_back(atoi("1"));
                                    out_file.time_seq_list.push_back(j);
                                }
                            }
                            //向下失稳
                            if ((out_file.gen_info[GenID[genid]].Angle[j - 1] < out_file.gen_info[GenID[genid]].Angle[j]))
                            {
                                if (abs(out_file.gen_info[GenID[genid]].Angle[j - 1] - out_file.gen_info[GenID[genid]].Angle[j]) > 200)
                                {
                                    out_file.direction_list.push_back(atoi("-1"));
                                    out_file.time_seq_list.push_back(j);
                                }
                            }
                        }
                        if (out_file.time_seq_list.size() > 0)
                        {
                            for (unsigned int i = 0; i < out_file.time_seq_list.size() - 1; i++)
                            {
                                int TIMES = 0;//用于决定加上多少个360度
                                for (unsigned int k = 0; k < i; k++)
                                {
                                    TIMES = TIMES + out_file.direction_list[k];
                                }
                                for (int j = out_file.time_seq_list[i]; j < out_file.time_seq_list[i + 1]; j++)
                                {
                                    out_file.gen_info[GenID[genid]].Angle[j] = out_file.gen_info[GenID[genid]].Angle[j] + 360 * (TIMES + out_file.direction_list[i]);
                                }
                            }
                            //把最后一段也补上
                            int TOTALTIMES = 0;
                            for (unsigned int i = 0; i < out_file.direction_list.size(); i++)
                            {
                                TOTALTIMES = TOTALTIMES + out_file.direction_list[i];
                            }
                            for (unsigned int l = out_file.time_seq_list[out_file.time_seq_list.size() - 1]; l < out_file.gen_info[GenID[genid]].Angle.size(); l++)
                            {
                                out_file.gen_info[GenID[genid]].Angle[l] = out_file.gen_info[GenID[genid]].Angle[l] + 360 * TOTALTIMES;
                            }
                        }
                    }
                    //确定失稳的周波范围
                    for (unsigned int j = 1; j < out_file.gen_info[GenID1].Angle.size(); j++)
                    {
                        double AngleDiff1 = abs(out_file.gen_info[GenID1].Angle[j] - out_file.gen_info[GenID2].Angle[j]);
                        double AngleDiff2 = abs(out_file.gen_info[GenID1].Angle[j - 1] - out_file.gen_info[GenID2].Angle[j - 1]);
                        if (AngleDiff1>500 && AngleDiff2 < 500)
                        {
                            out_file.gen_out_limit_time_start_list.push_back(out_file.gen_info[GenID1].ATime[j]);
                        }
                        if (AngleDiff1 < 500 && AngleDiff2>500)
                        {
                            out_file.gen_out_limit_time_end_list.push_back(out_file.gen_info[GenID1].ATime[j]);
                        }
                        if (AngleDiff1>500 && AngleDiff2 > 500)
                        {
                            if (j == out_file.gen_info[GenID[GenID1]].Angle.size() - 1)
                            {
                                out_file.gen_out_limit_time_end_list.push_back(out_file.gen_info[GenID1].ATime[j]);
                            }
                        }
                    }
                }
            }
        }
    }


    // 统计节点失稳信息
    for (unsigned int i = 0; i < out_file.buswarning_list.size(); i++)
    {
        out_file.sigle_bus_out_limit_time_start_list.clear();
        out_file.sigle_bus_out_limit_time_end_list.clear();
        Out::BusOutLimitTime BusOutLimitTimeStartTemp;
        Out::BusOutLimitTime BusOutLimitTimeEndTemp;
        BusOutLimitTimeStartTemp.BusName = out_file.buswarning_list[i].BusNamewithVol.c_str();
        BusOutLimitTimeEndTemp.BusName = out_file.buswarning_list[i].BusNamewithVol.c_str();
        out_file.bus_out_limit_time_start_list.push_back(BusOutLimitTimeStartTemp);
        out_file.bus_out_limit_time_end_list.push_back(BusOutLimitTimeEndTemp);
        if (strstr(out_file.buswarning_list[i].InstabilityJudgeType.c_str(), "频率"))
        {
            if (out_file.bus_info.size() > 0)
            {
                for (unsigned int j = 0; j < out_file.bus_info.size(); j++)
                {
                    if (out_file.bus_info[j].FrequencyDeviation.size() > 0)
                    {
                        if (strstr(out_file.bus_info[j].Name.c_str(), out_file.buswarning_list[i].InstabilityEquipmentName.c_str()))
                        {
                            for (unsigned int k = 0; k < out_file.bus_info[j].FrequencyDeviation.size() - 1; k++)
                            {
                                //越上限
                                if ((out_file.bus_info[j].FrequencyDeviation[k] < 10) && (out_file.bus_info[j].FrequencyDeviation[k + 1]>10))
                                {
                                    out_file.sigle_bus_out_limit_time_start_list.push_back(out_file.bus_info[j].FDTime[k]);
                                }
                                if ((out_file.bus_info[j].FrequencyDeviation[k] > 10) && (out_file.bus_info[j].FrequencyDeviation[k + 1]<10))
                                {
                                    out_file.sigle_bus_out_limit_time_end_list.push_back(out_file.bus_info[j].FDTime[k]);
                                }
                                ///////////////越下限/////////////////
                                if ((out_file.bus_info[j].FrequencyDeviation[k]>-10) && (out_file.bus_info[j].FrequencyDeviation[k + 1] < -10))
                                {
                                    out_file.sigle_bus_out_limit_time_start_list.push_back(out_file.bus_info[j].FDTime[k]);
                                }
                                if ((out_file.bus_info[j].FrequencyDeviation[k]<-10) && (out_file.bus_info[j].FrequencyDeviation[k + 1]>-10))
                                {
                                    out_file.sigle_bus_out_limit_time_end_list.push_back(out_file.bus_info[j].FDTime[k]);
                                }
                            }
                            if ((out_file.sigle_bus_out_limit_time_start_list.size() + out_file.sigle_bus_out_limit_time_end_list.size()) % 2 == 1)
                            {
                                //////如果是奇数，就说明是有一段到周波结束时还是失稳的,于是把最后一个结尾周波补上///////
                                out_file.sigle_bus_out_limit_time_end_list.push_back(out_file.bus_info[j].FDTime[out_file.bus_info[j].FDTime.size() - 1]);
                            }
                        }
                    }
                }
            }
        }
        /////////////得到最终的失稳周波段//////////////
        for (unsigned int m = 0; m < out_file.sigle_bus_out_limit_time_start_list.size(); m++)
        {
            if (abs(out_file.sigle_bus_out_limit_time_end_list[m] - out_file.sigle_bus_out_limit_time_start_list[m]) >= 100)
            {
                double BOLTS = out_file.sigle_bus_out_limit_time_start_list[m];
                double BOLTE = out_file.sigle_bus_out_limit_time_end_list[m];
                out_file.bus_out_limit_time_start_list[i].OutLimitTime.push_back(BOLTS);
                out_file.bus_out_limit_time_end_list[i].OutLimitTime.push_back(BOLTE);
            }
        }
    }

}

